package fr.jibhaine.synth
{
	import flash.events.SampleDataEvent;
	
	/**
	 * This class contains fonction to generate basic waveforms
	 * @author Benjamin Legrand 
	 */
	public class WaveGenerator
	{
		
		private const BUFFER_SIZE:int		= 8192;
		
		private const SAMPLING_RATE:int 	= 44100;
		
		private const TWO_PI:Number 		= 2*Math.PI;
		
		private const TWO_PI_OVER_SR:Number = TWO_PI/SAMPLING_RATE;
		
		public var FREQUENCY:Number 		= 440;
		
		public var currentWaveFunction:Function;
		
		/**
		 * Build a wave generator object 
		 * */
		public function WaveGenerator(waveForm:String)
		{
				switch(waveForm){
					case "sine": 		currentWaveFunction = sineWave;		break;
					case "square": 		currentWaveFunction = squareWave;	break;
					case "triangle": 	currentWaveFunction = triangleWave;	break;
					case "sawtooth": 	currentWaveFunction = sawtoothWave;	break;
					case "pulse": 		currentWaveFunction = pulseWave;	break;
					case "noise": 		currentWaveFunction = noiseWave;	break;
					default :			currentWaveFunction = sineWave;		break;
				}
		}
		
		/**
		 * Generate a sine wave
		 */
		public function sineWave(event:SampleDataEvent):void{
			var sample:Number;
		    for ( var c:int=0; c<BUFFER_SIZE; c++ ) {
		      sample = Math.sin((Number(c+event.position) * TWO_PI_OVER_SR * FREQUENCY)) * 0.15 ;
		      event.data.writeFloat(sample);
		      event.data.writeFloat(sample);
		    }
		}
		
		/**
		 * Generate a square wave
		 */
		public function squareWave(event:SampleDataEvent):void{
		    var amp:Number = 0.075;
		    var sample:Number;
		    for (var i:int=0; i<8192; i++) {
		        sample = Math.sin((i + event.position) * TWO_PI_OVER_SR * FREQUENCY) > 0 ? amp : -amp;
		        event.data.writeFloat(sample);
		        event.data.writeFloat(sample);
		    }
		}
		
		public function triangleWave(event:SampleDataEvent):void{
			
		}
		
		public function sawtoothWave(event:SampleDataEvent):void{
			
		}
		
		public function pulseWave(event:SampleDataEvent):void{
			
		}
		
		public function noiseWave(event:SampleDataEvent):void{
			
		}
	}
}